package notes.java.concurrent;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.TimeUnit;

/** 生产者，消费者实现 wait notify*/
public class U17_TestLockSupport {

    // 最大生产数量
    private int MAX_NUM = 10;
    // 消费到此数时，停止消费
    private int MIN_NUM = 0;
    // 容器
    private Queue<String> queue = new LinkedList<>();
    // 锁
    private Object lock = new Object();

    /** 生产者*/
    class Producer extends Thread{

        @Override
        public void run() {
            // 生产
            try {
                add();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        private void add() throws InterruptedException {
            while(true) {
                TimeUnit.SECONDS.sleep(1); // 休息1秒
                synchronized(lock) {
                    while(queue.size() == MAX_NUM) {
                        System.out.println("满了。。。");
                        lock.wait();
                    }
                    queue.add("商品");
                    System.out.println(Thread.currentThread().getName() + "添加了一个商品。。。当前容器大小：" + queue.size());
                    lock.notify();
                }
            }
        }
    }

    /** 消费者*/
    class Consumer extends Thread{
        @Override
        public void run() {
            // 消费
            try {
                get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        private void get() throws InterruptedException {
            while(true) {
                synchronized(lock) {
                    while(queue.size() == MIN_NUM) {
                        System.out.println("消费完了。。。");
                        lock.wait();
                    }
                    queue.poll();
                    lock.notify();
                    System.out.println(Thread.currentThread().getName() + "消费了一个商品。。。当前容器大小：" + queue.size());
                }
                TimeUnit.SECONDS.sleep(1); // 休息1秒
            }
        }
    }

    public static void main(String[] args) {

        U17_TestLockSupport t = new U17_TestLockSupport();
        // 3个生产者
        for(int i = 0; i<3; i++) {
            new Thread(t.new Producer(), "线程" + i).start();
        }

        // 6个消费者
        for(int i = 0; i<6; i++) {
            new Thread(t.new Consumer(), "线程" + i).start();
        }
    }
}